﻿#region Copyright Jonathan Quiros

//	
// All rights are reserved. Reproduction or transmission in whole or in 
// part, in any form or by any means, electronic, mechanical or otherwise, 
// is prohibited without the prior written consent of the copyright owner.
//
// Filename: PartiesController.cs
//

#endregion

using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.Mvc;
using Ids.Utils;
using Novagoal.Logic;
using Novagoal.Models;
using Novagoal.Utils;
using Novagoal.Website.Models.Forms;
using Novagoal.Website.Models.Views;
using Novagoal.Website.WebApp.Helpers;
using Novagoal.Website.WebApp.Routing;

namespace Novagoal.Website.WebApp.Controllers
{
    public class PartiesController : ListController
    {
        #region PROPERTIES

        private readonly GamesLogic _gamesLogic;
        private readonly PartiesLogic _partiesLogic;
        private readonly TournamentsLogic _tournamentsLogic;

        #endregion

        #region PUBLIC METHODS

        public PartiesController(UsersLogic usersLogic, GamesLogic gamesLogic, PartiesLogic partiesLogic, TournamentsLogic tournamentsLogic) : base(usersLogic)
        {
            _gamesLogic = gamesLogic;
            _partiesLogic = partiesLogic;
            _tournamentsLogic = tournamentsLogic;
        }

        [HttpGet]
        public ActionResult Index()
        {
            var currentUser = GetUserInformation();
            var parties = _partiesLogic.GetParties(Request.Params, SortField, SortDirection, PageNumber, PageSize);

            var indexViewModel = new IndexViewModel
            {
                List = parties,
                RouteValues = parties.GetRouteValues(PageSize),
                Members = _partiesLogic.GetAllPartyMembers(),
            };
            return View("Index"+currentUser.Person.Language, indexViewModel);
        }

        [HttpPost]
        public ActionResult Index(FormCollection collection)
        {
            return Redirect(collection);
        }

        [HttpGet]
        public ActionResult Add()
        {
            var model = new PartiesViewModel
            {
                Party = new Party(),
                Members = new List<Person>(),
                People = _partiesLogic.GetPeopleNotInParty(0),
                Tournaments = _tournamentsLogic.GetOpenTournaments()
            };
            return View("Details", model);
        }

        [HttpGet]
        public ActionResult Edit(int id)
        {
            var currentUser = GetUserInformation();
            var party = _partiesLogic.GetParty(id);
            if(currentUser.Role != Enums.Roles.SuperUser.ToStringValue() && party.CreatedBy.Id != currentUser.Person.Id)
            {
                throw new UnauthorizedAccessException("You don't have permissions to edit this party");
            }
            
            var model = new PartiesViewModel
                            {
                                Party = party ?? new Party(),
                                Members = _partiesLogic.GetPartyMembers(id),
                                People = _partiesLogic.GetPeopleNotInParty(id),
                                Tournaments = _tournamentsLogic.GetOpenTournaments()
                            };
            if(party == null)
            {
                TempData.SetMessage("The party is invalid", MessageType.Warning);
            }
            return View("Details", model);
        }

        [HttpPost]
        public ActionResult Save(PartyFormModel formModel)
        {
            var modelView = ModelViewFromForm(formModel);
            if (ModelState.IsValid)
            {
                modelView.Party.Id = _partiesLogic.Save(modelView.Party);
                _partiesLogic.AddMembers(formModel.MemberId, modelView.Party.Id);
                modelView.SuccessMessage = "Party saved successfully";
                modelView.Members = _partiesLogic.GetPartyMembers(modelView.Party.Id);
            }

            return View("Details", modelView);
        }

        [HttpGet]
        public ActionResult View(int id)
        {
            var currentUser = GetUserInformation();
            var party = _partiesLogic.GetParty(id);
            if (currentUser.Role != Enums.Roles.SuperUser.ToStringValue() && party.CreatedBy.Id != 
                currentUser.Person.Id && !_partiesLogic.IsPersonAMember(id, currentUser.Person.Id))
            {
                throw new UnauthorizedAccessException("You don't have permissions to view this party");
            }

            var finishedGames = _gamesLogic.AllFinishedGames(party.Tournament.Id);

            var model = new PartiesMainViewModel
                            {
                                Party = party,
                                FavoriteTeam = _partiesLogic.GetFavoriteTeam(currentUser.Person.Id, party.Id),
                                FinishedGames = finishedGames.OrderByDescending(g => g.StartedAt).ToList(),
                                Ranking = _partiesLogic.GetRanking(party.Id)
                            };
            return View("View"+currentUser.Person.Language, model);
        }

        [HttpPost]
        public JsonResult SetFavoriteTeam(int partyId, int teamId)
        {
            var status = true;
            var message = string.Empty;
            try
            {
                var currentUser = GetUserInformation();
                _partiesLogic.SetFavoriteTeam(partyId, teamId, currentUser.Person.Id);
            }
            catch(Exception exception)
            {
                status = false;
                message = exception.Message;
            }
            return Json(new { Status = status, Messages = message }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult PublishMessage(int partyId, string message)
        {
            var status = true;
            var error = string.Empty;
            try
            {
                var currentUser = GetUserInformation();
                _partiesLogic.AddMessage(partyId, currentUser.Person.Id, message);
            }
            catch (Exception exception)
            {
                status = false;
                error = exception.Message;
            }
            return Json(new { Status = status, Messages = error }, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public ActionResult Messages(int partyId)
        {
            var messages = _partiesLogic.GetMessages(partyId);
            return PartialView(messages);
        }
        
        #endregion

        #region PRIVATE METHODS

        private PartiesViewModel ModelViewFromForm(PartyFormModel formModel)
        {
            var currentUser = GetUserInformation();
            return new PartiesViewModel
                       {
                           Tournaments = _tournamentsLogic.GetOpenTournaments(),
                           Members = _partiesLogic.GetPartyMembers(formModel.PartyId),
                           People = _partiesLogic.GetPeopleNotInParty(formModel.PartyId),
                           Party =
                               new Party
                                   {
                                       Id = formModel.PartyId,
                                       Name = formModel.Name,
                                       Tournament = new Tournament {Id = formModel.TournamentId},
                                       CreatedBy = new Person { Id = currentUser.Person.Id },
                                       UpdatedBy = SecurityContext.User.Id
                                   }
                       };
        }

        #endregion
    }
}
